package com.ericcarlisle.howler
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.ID3Info;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;

	public class Player extends EventDispatcher
	{
		[Bindable] public var playMode:String = PlayModes.INIT;				// Play mode.
		[Bindable] public var playList:PlayList = new PlayList();			// Play list.
		[Bindable] public var position:uint = 0;							// Channel position (in milliseconds).
		[Bindable] public var sound:Sound = new Sound();					// Sound object for current sound.
		public var channel:SoundChannel = new SoundChannel();				// Sound channel.

		private var transform:SoundTransform = new SoundTransform(volume);	// Sound transform.
		private var volume:Number = 0.5;									// Volume.
		private var soundLoader:Sound;										// Sound object for loading sound info into playlist.

		public function Player(){}
		
		public function loadToList(files:Array):void
		{
			// Iterate through selected files and load as sound objects.				
			for(var i:uint = 0; i < files.length; i++)
			{
				if (files[i].isDirectory)
				{
					loadToList(files[i].getDirectoryListing());
				}	
				else
				{
					soundLoader = new Sound(new URLRequest(files[i].url));
					soundLoader.addEventListener(Event.COMPLETE, loadToList_CompleteHandler);
				}
			}
		}
		
		private function loadToList_CompleteHandler(event:Event):void
		{
			// Declare variables for all needed sound information.
			soundLoader = Sound(event.target);
			var duration:Number = soundLoader.length;
			var id3:ID3Info = soundLoader.id3;
			var url:String = soundLoader.url;
			
			// Add sound info and ID3 metadata to playlist.
			if (playList.addSound(id3.songName, id3.album, id3.artist, id3.track, id3.year, id3.genre, duration, url))
			{
				// Dispatch the "playlist change" event.
				dispatchEvent(new Event(PlayerEvents.PLAYLIST_CHANGE));
			}
			
			// clean up.
			soundLoader.removeEventListener(Event.COMPLETE, loadToList_CompleteHandler);
			soundLoader = null;
		}

		/**
		 * Plays a sound of specified index from the player list.
		 * 
		 * @param index Index of the sound to play from the player's list.
		 * @see com.ericcarlisle.howler.PlayList
		 */
		public function loadToPlay(index:uint):void
		{	
			this.playMode = PlayModes.LOADING;
			playList.index = index;
			this.sound = new Sound(new URLRequest(playList[index]["url"]));
			this.sound.addEventListener(Event.OPEN,loadToPlay_OpenHandler);
		}	
		
		private function loadToPlay_OpenHandler(event:Event):void
		{
			// Get sound object from event and apply event handlers..
			this.sound = event.target as Sound;
			this.sound.removeEventListener(Event.OPEN, play);
			this.play(0);
		}
		
		
		public function play(position:int=-1):void
		{	
			// Play sound and set playmode.
			if (position != -1) this.position = position;
			channel = sound.play(position,0,transform);
			channel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
			playMode = PlayModes.PLAY;
		}
		
		private function soundCompleteHandler(event:Event):void
		{
			this.stop();
			this.channel.removeEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
			if (this.playList.index < this.playList.length-1)
			{
				this.next();
			}
		}
		
		/**
		 * Pauses the current sound.
		 */
		public function pause():void
		{
			this.playMode = PlayModes.PAUSE;
			this.position = channel.position;
			this.channel.stop();
			
		}

		/**
		 * Stops the current sound.
		 */
		public function stop():void
		{
			this.playMode = PlayModes.STOP;
			this.channel.stop();
			this.position = 0;
			
		}
		
		/**
		 * Plays the previous sound on the player's list.
		 */
		public function back():void
		{
			this.stop();
			this.playList.index--;
			this.loadToPlay(this.playList.index);
		}

		/**
		 * Plays the next sound on the player's list.
		 */
		public function next():void
		{
			this.stop();
			this.playList.index++;
			this.loadToPlay(this.playList.index);
		}

		/**
		 * Sets the player's volume (0-100).
		 */
		public function setVolume(volume:uint):void
		{
			this.volume = volume/100;
			this.transform.volume = this.volume;
			this.channel.soundTransform = this.transform;
		}
	}
}